import {Component, Input, OnInit, OnChanges, SimpleChanges, OnDestroy} from '@angular/core';
import {BehaviorSubject, Subject} from "rxjs";
import {distinctUntilChanged, takeUntil} from "rxjs/operators";

@Component({
  selector: 'app-spin',
  template: `
    <div
      *ngIf="isLoading"
      class="spin"
      [class.spining]="isLoading">
      <div class="circle"></div>
      <div class="circle"></div>
      <div class="circle"></div>
      <div class="circle"></div>
    </div>
    <span *ngIf="isLoading" class="loading-text" >
      Loading ...
    </span>
  `,
  styles: [
    `
      :host {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
      }
      .loading-text {
        padding-top: 5px;
        color: #3893ee;
        opacity: .4;
        animation: spinMove .6s infinite alternate;
      }
      .spin {
        position: relative;
        display: inline-grid;
        width: 32px;
        height: 32px;
        grid-template-rows: repeat(2, 1fr);
        grid-template-columns: repeat(2, 1fr);
        grid-gap: 2px;
        transform: rotate(45deg);
        transform-origin: center;
      }
      @keyframes spinx {
        to {
          transform: rotate(405deg);
          transform-origin: center;
        }
      }
      @keyframes spinMove {
        to {
          opacity: 1;
        }
      }
      .spining {
        animation: spinx 1.2s linear infinite;
      }
      .circle {
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #4294ea;
        border-radius: 50%;
        width: 12px;
        height: 12px;
        opacity: .3;
        animation: spinMove 1.2s linear infinite alternate;
      }
      .circle:nth-child(2) {
        animation-delay: .4s;
      }
      .circle:nth-child(3) {
        animation-delay: .8s;
      }
      .circle:nth-child(4) {
        animation-delay: 1.2s;
      }
    `
  ]
})
export class SpinComponent implements OnInit, OnChanges, OnDestroy {
  @Input() spinning: boolean = false
  private spinning$ = new BehaviorSubject<boolean>(this.spinning)
  private destroy$ = new Subject<void>();
  isLoading = false;
  constructor() { }

  ngOnInit(): void {
    const loading$ = this.spinning$.pipe(
      distinctUntilChanged(),
      takeUntil(this.destroy$)
    )
    loading$.subscribe(loading => {
      this.isLoading = loading;
    })
  }
  ngOnChanges(changes: SimpleChanges) {
     const { spinning } = changes
     if (spinning) {
      this.spinning$.next(this.spinning)
     }
  }
  ngOnDestroy() {
    this.destroy$.next()
    this.destroy$.complete()
  }
}
